第21章 时序数据库
第21章 时序数据库
一、概念
时间序列数据库(TSDB)是针对时间戳或时间序列数据而优化的数据库。
时间序列数据只是一段时间内跟踪、监控、下采样和汇总的测量或事件。这可能是服务器指标、应用程序性能监控、网络数据、传感器数据、事件、点击、市场交易以及许多其他类型的分析数据。
时间序列数据库专门用于处理带有时间戳的度量和事件或度量。
TSDB被优化用于测量随时间的变化。使时间序列数据与其他数据工作负载非常不同的属性是数据生命周期管理、摘要和许多记录的大范围扫描。
时序数据库的生命周期一般比较短,比如一个传感器,可能我们只关心最近一周的或者一个月的数据,超过的时间的数据就可以删除。(类比关系型数据库的订单数据,订单数据必须要持久化保存,但是这种时序数据库可以通过摘要压缩一下,或者直接删掉)
不太可能会建立索引,例如记录温度随时间的变化,一般不会有必要建立索引(比如建个温度在时间的索引,这没有意义)
对于时序数据库接受的数据的特点:更多的数据点,更多的数据源,更多的监控,更多的控制
InfluxDB排名时序数据库第一
二、优化
- 可以不记录时间戳:如果传输来的数据比较稳定的话,例如每秒1个数据,我可以记录某一个特定数据(比如开始的数据的时间戳)然后后面每秒记录一个数据就好。
- 可以记录数据的增量:比如记录温度,变化比较小。我就记录相比上一个数据增加或者减少了多少度。这样存储的数据的空间得以节省了,所以可以存更多的数据。
三、InfluxDB存储
- 存储是以桶来存储的,
my_bucket
就是相当于表名。 - 注意:带有
_
开头的,都是系统保留的字段,也就是一定会有的一个列,反之都是用户自定义的字段 _time
:时间戳,数据对应的时间,因为可能同一个时间会接收到很多数据,所以很可能同一个时间接收到很多数据,所以时间戳不能唯一的标识。时间戳非常准确,精确到纳秒级别。_measurement
:起一个名字,一个统称,这个表格在干啥。census
就是调查种群数量。_field
:存储的是key,比如下表里面存储的就是某个物种的名字_value
:存储的是值,类型可以是strings, floats, integers, or booleans,之所以不能是别的,是因为如果是复杂的数据类型转换会耽误时间,效率降低,所以就只能存这些基础的数据类型。TagValue
和_
开头的字段的差别就是:前者可以建立索引,后者不会建立索引。例如下图里面我要统计所有叫mullen
的科学家的数据有哪些,系统就会根据索引去查找,但是如果根据_field
查找,系统就会做全表扫描。Tag的含义就是打标签。Field_set
:数据集,根某一个时间戳关联的所有的key-value的数据集就是Field-set
Tag_Set
:标签集合,根某一个特定标签值关联的,所有的数据集
四、Field和Tag的区别
Field
不建立索引,是必要组成部分- 根
Field
相关的查询,必须经过全表扫描,然后匹配检测 - 带有
>
标记的查询往往效率更高,因为数据都是按照追加的方法,如果能给一个时间范围查找效率就更高。 Tag
是可选的,不是必要的组成部分Tag
会建立索引,对于Tag
相关的查询更快- 对于经常要查询的列作为一个
Tag
,会是一个很好的选择
五、查询示范
from(bucket: "bucket-name")
|> range(start: 2022-09-12T00:00:00Z, stop: 2022-09-19T00:00:00Z)
|> filter(fn: (r) => r._field == "bees" and r._value == 30)
六、关系图
- Series:measurement, tag set, 和field key都相同的点集合
- Point:一个数据点,带有时间戳的数据点
- Bucket:存储桶,归属于一个组织,存储相对应的数据点集合
- Organization:对于一组用户的公共组织空间
七、数据库设计原则
- 严格按照时间组织,按照时间顺序递增追加
- 严格的更新和删除数据的策略,毕竟很多数据都是类似传感器发来的数据,需要修改或者删除数据需要有较高的权限。删除数据只能删除已经落硬盘的数据,不能删除正在写入的数据。
- 数据优先读、然后是写入,然后是其他类型的数据。因此如果高频率的插入数据,在某次查询的时候,可能不会包含最新的数据。
- InluxDB使用无模式设计来更好地管理不连续数据。时间序列数据通常是短暂的,这意味着数据会出现几个小时,然后消失。例如,一个新主机启动并报告一段时间,然后关闭。
- 因为数据集比单个点更重要,所以InfluxDB实现了强大的工具来聚合数据和处理大型数据集。点通过时间戳和序列来区分,因此没有传统意义上的ID。
- 重复的数据的处理:InluxDB假设多次发送的数据是重复数据。相同的点不会存储两次。比如除了value之外的部分数据都是相同的,这样的数据提交了三次,不会像mysql一样插入三行相同的数据,InluxDB会用最新的一个数据存储。
八、存储引擎
- 数据存储分为L0、L1、L2……,一般L0是内存,后面的是硬盘级别的存储。整体是一个金字塔的结构,下一级别的存储一般是上一级存储的10倍。
- 内存分为活跃区域和不活跃区域,活跃区域写满了之后,就开始把活跃区域的数据落硬盘,此时活跃区域变成不活跃区域被锁;不活跃的区域变成活跃区域,开始接受新数据的写入。
- L1的层次一般来说不会做数据的归并,可能有一个块存的是key位1-500的,一个快存储的是1-30的数据。因此有重叠
- 但是从L2开始就不会有重叠类型的数据了。
- 越往下沉的数据一般是不活跃的数据,当一个查询开始的时候,优先在内存区域查找,然后向下一层L1查找,然后向下一层L2查找,然后向L3,直到找到数据为止。